package com.rc.web.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.row.Row;
import com.mybatisflex.core.row.RowUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.rc.common.constant.Code;
import com.rc.common.constant.OrderStatusType;
import com.rc.common.constant.OrderType;
import com.rc.common.exception.BusinessException;
import com.rc.common.util.RabbitMqHelper;
import com.rc.pojo.dto.order.OrderFormDTO;
import com.rc.pojo.dto.order.OrderQuery;
import com.rc.pojo.po.*;
import com.rc.pojo.vo.order.OrderPayListVO;
import com.rc.pojo.vo.order.OrderPayVO;
import com.rc.pojo.vo.order.OrderVO;
import com.rc.pojo.vo.order.PageOrderVO;
import com.rc.web.converter.OrderConverter;
import com.rc.web.mapper.OrderMapper;
import com.rc.web.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 *  服务层实现。
 *
 * @author sym
 * @since 2024-06-05
 */
/**
 * 订单服务实现类
 * 提供订单相关的业务逻辑实现
 */
@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    // 活动服务
    private final ActivityService activityService;
    // 认养服务
    private final AdoptionService adoptionService;
    // 订单转换器
    private final OrderConverter orderConverter;
    // 消费者服务
    private final ConsumerService consumerService;
    // RabbitMQ助手
    private final RabbitMqHelper rabbitMqHelper;
    // 植物项服务
    private final PlantItemService plantItemService;
    // 认养信息服务
    private final AdoptionInfoService infoService;
    // 地址服务
    private final AddressService addressService;

    /**
     * 创建订单
     * @param dto 订单表单DTO
     * @return 创建的订单对象
     */
    @Override
    @Transactional
    public Order createOrder(OrderFormDTO dto) {
        // 获取订单类型和商品ID
        Integer type = dto.getType();
        Long itemId = dto.getItemId();

        // 转换DTO为订单对象
        Order order = orderConverter.formDTO2DO(dto);

        // 根据订单类型设置订单信息
        switch (type){
            case OrderType.ADOPTION -> { // 认养订单
                Adoption adoption = adoptionService.getByIdOpt(itemId)
                        .orElseThrow(() -> new BusinessException(Code.NO_SUCH_ADOPTION));
                orderConverter.updateByAdoption(adoption, order);
                order.setStatus(OrderStatusType.UN_PAY);
            }

            case OrderType.ACTIVITY -> { // 活动订单
                Activity activityServiceById = activityService.getByIdOpt(itemId)
                        .orElseThrow(() -> new BusinessException(Code.NO_SUCH_ACTIVITY));
                orderConverter.updateByActivity(activityServiceById, order);
                order.setStatus(OrderStatusType.UN_PAY);
            }

            case OrderType.RECHARGE -> { // 充值订单
                consumerService.deductMoney(new BigDecimal(-1000));
                BigDecimal amount = new BigDecimal(1000);
                LocalDateTime now = LocalDateTime.now();
                order.setTitle("充值");
                order.setNum(1);
                order.setDescription("系统充值");
                order.setTotalFee(amount);
                order.setPrice(amount);
                order.setEndTime(now);
                order.setPayTime(now);
                order.setConsignTime(now);
                order.setType(OrderType.RECHARGE);
                order.setStatus(OrderStatusType.FINISH);
            }
        }

        // 保存订单
        this.save(order);

        // 发送延迟消息，15分钟内未支付则标记为取消
        rabbitMqHelper.sendDelayMessage(
                "order.exchange",
                "order.expiration",
                order.getId(),
                15 * 60 * 60 * 1000);

        return order;
    }

    /**
     * 获取当前用户的订单列表
     * @return 订单VO列表
     */
    @Override
    public List<OrderVO> getConOrderList() {
        List<Row> rowList = mapper.selectListByConId(StpUtil.getLoginIdAsLong());
        List<OrderVO> orderList = RowUtil.toObjectList(rowList, OrderVO.class);
        return orderList.stream()
                .sorted(Comparator.comparing(OrderVO::getCreateTime).reversed())
                .toList();
    }

    /**
     * 支付订单
     * @param orderId 订单ID
     * @param addressId 地址ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void payOrder(Long orderId,Long addressId) {
        // 获取订单
        Order order = mapper.selectOneById(orderId);

        // 检查订单状态
        if (order == null || order.getStatus() != OrderStatusType.UN_PAY){
            throw new BusinessException(Code.ORDER_STATUS_EXCEPTION);
        }

        // 从用户余额扣款
        consumerService.deductMoney(order.getTotalFee());

        // 根据订单类型处理
        switch (order.getType()){
            case OrderType.ADOPTION -> { // 认养订单
                order.setStatus(OrderStatusType.UN_CONFIRM);

                // 获取认养信息和植物信息
                Adoption adoption = adoptionService.getById(order.getItemId());
                PlantItem plantItem = plantItemService.adoption(adoption.getPlantId());
                Address address = addressService.getById(addressId);

                // 创建认养信息
                AdoptionInfo adoptionInfo = AdoptionInfo.builder()
                        .orderId(orderId)
                        .cover(plantItem.getCover())
                        .price(order.getPrice())
                        .address(String.format("%s %s %s %s",address.getProvince(),address.getCity(),address.getTown(),address.getStreet()))
                        .treeName(plantItem.getName())
                        .plantItemId(plantItem.getId())
                        .build();

                infoService.save(adoptionInfo);
            }

            case OrderType.ACTIVITY -> { // 活动订单
                order.setStatus(OrderStatusType.UN_CONFIRM);
                order.setEndTime(LocalDateTime.now());
            }
        }

        // 更新支付时间
        order.setPayTime(LocalDateTime.now());
        this.updateById(order);
    }

    @Override
    public Page<PageOrderVO> getPage(OrderQuery dto) {
        return mapper.selectPage(dto);
    }

    @Override
    public int getItemTodaySold(Long itemId, Integer type) {
        return (int) mapper.selectCountByFormat(itemId,type,"yyyy-MM-dd");
    }

    @Override
    public OrderVO getOneById(Long id) {
        Order byId = this.getById(id);
        return orderConverter.toVO(byId);
    }

    @Override
    public List<OrderPayListVO> getPayList() {
        List<Order> orders = mapper.selectPayLisByConId(StpUtil.getLoginIdAsLong());

        Map<LocalDate, List<OrderPayVO>> map= orders.stream()
                .filter(order -> order.getStatus() > OrderStatusType.CANCEL)
                .map(orderConverter::toPayVO)
                //根据创建时间的年月进行分组
                .collect(Collectors.groupingBy(item -> item.getPayTime().toLocalDate()));

        return map.keySet().stream()
                .map(key -> OrderPayListVO.builder()
                        .time(key)
                        .list(map.get(key))
                        .build())
                .toList();
    }

    @Override
    public void cancelOder(Long orderId) {
        Order order = this.getById(orderId);

        if (order == null || order.getStatus() != OrderStatusType.UN_PAY) {
            throw new BusinessException(Code.ORDER_STATUS_EXCEPTION);
        }

        order.setStatus(OrderStatusType.CANCEL);
        this.updateById(order);
    }

    @Override
    public void verifyOrder(Long orderId) {
        Order order = this.getById(orderId);

        if (order == null || order.getStatus() < OrderStatusType.UN_CONFIRM) {
            throw new BusinessException(Code.ORDER_STATUS_EXCEPTION);
        }

        order.setStatus(OrderStatusType.CONFIRM);
        this.updateById(order);
    }
}
